﻿using System.Text.Json;

namespace MiddlewareTestWebApp
{
    public class MyWebApiMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ActionLocator _actionLocator;

        public MyWebApiMiddleware(RequestDelegate next, ActionLocator actionLocator)
        {
            _next = next;
            _actionLocator = actionLocator;
        }

        public async Task InvokeAsync(HttpContext context, IServiceProvider sp)
        {
            (bool ok, string? ctrlName, string? actionName) = PathParser.Parse(context.Request.Path);
            if (ok==false)
            {
                await _next(context);
                return;
            }

            // 使用控制器的名字和操作方法的名字来加载控制器方法对于的MethodInfo类型的对象
            var actionMethod = _actionLocator.LocateActionMetod(ctrlName!, actionName!);
            if (actionMethod == null)
            {
                await _next(context);
                return;
            }
            Type controllerType = actionMethod.DeclaringType!;
            object? controller = sp.GetService(controllerType);
            var paraValues = BindingHelper.GetParameterValues(context, actionMethod);
            foreach (var filter in ActionFilters.Filters)
            {
                filter.Execute();
            }
            var result = actionMethod.Invoke(controller, paraValues);
            // 限定返回值只能是普通类型，不能是IActionResult类型
            string jsonStr = JsonSerializer.Serialize(result);
            context.Response.ContentType = "application/json";
            context.Response.StatusCode = 200;
            await context.Response.WriteAsync(jsonStr);
        }
    }
}
